package com.shux.usermanager.shiro;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.shux.common.exception.ShuxRunTimeException;
import com.shux.common.token.ShuxUsernamePasswordToken;
import com.shux.usermanager.biz.ISysMenuBiz;
import com.shux.usermanager.biz.ISysRoleBiz;
import com.shux.usermanager.biz.ISysUserBiz;
import com.shux.usermanager.constant.UserConstant;
import com.shux.usermanager.entity.SysMenu;
import com.shux.usermanager.entity.SysRole;
import com.shux.usermanager.entity.SysUser;
import com.shux.utils.constants.Constant;
import com.shux.utils.other.RightsHelper;
import com.shux.utils.page.PageData;
import com.shux.utils.string.StringUtil;

/**
 **********************************************
 *  描述：后台认证拦截器
 * Simba.Hua
 * 2017年5月30日
 **********************************************
**/
public class UsermanagerShiroRealmInterceptor extends AuthorizingRealm{
    private @Autowired ISysUserBiz sysUserBiz;
    private @Autowired ISysMenuBiz sysMenuBiz;
    private @Autowired ISysRoleBiz sysRoleBiz;
    @Override
    public void setName(String name){
        super.setName("UsermanagerShiroRealmInterceptor");
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
        ShuxUsernamePasswordToken usertoken = (ShuxUsernamePasswordToken)token;
        String username = (String) usertoken.getPrincipal();
        PageData pageData = new PageData();
        pageData.put("userName", username);
        SysUser sysUser = sysUserBiz.getSysUserByUsername(pageData);
        if(null == sysUser){
            throw new ShuxRunTimeException(Constant.EXCEPTION_MESSAGE_USERNAME_PASSWORD_ISNOT_CORRECT);
        }
        SysRole sysrole = sysRoleBiz.loadSysRole(sysUser.getRoleId());
        sysUser.setRole(sysrole);
        if(!StringUtil.isEmpty(username) && sysUser !=null && !StringUtil.isEmpty(sysUser.getPassword())){
            sysUser.setLastLogin(new Date());
            sysUserBiz.updateSysUser(sysUser);
           return new SimpleAuthenticationInfo(sysUser,sysUser.getPassword(),getName());
        }
        return null;
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        /**
         * 
         */
        SysUser sysUser = (SysUser)principals.getPrimaryPrincipal();
        Map<String,String> permissionsMap = sysUserBiz.queryUserButtonAuth(sysUser.getUsername());
        List<String> permissions = new ArrayList<String>();
        List<SysMenu> allMenu = sysMenuBiz.queryAllMenu();
        
        if(permissionsMap != null && permissionsMap.size()>0){
            permissionsMap.forEach((key,value)->{
                if(UserConstant.BUTTON_PERMISSION.equals(value)){
                    permissions.add(key);//把有的权限加入到权限中
                }else{
                    permissions.addAll(getCommonAuthorization(allMenu,key,value));
                }
            });
        }
        SimpleAuthorizationInfo sai = new SimpleAuthorizationInfo();
        sai.addStringPermissions(permissions);
        return sai;
    }
    /**
     * 给定角色中的增、删、改、查
     * map.put("adds", sysrole.getAddAuth()); // 增
          map.put("dels", sysrole.getDelAuth()); // 删
          map.put("edits", sysrole.getEditAuth()); // 改
          map.put("querys", sysrole.getQueryAuth()); // 查
     * @param allMenu
     * @param haveAuth
     * @return
     */
    private List<String> getCommonAuthorization(List<SysMenu> allMenu,String operator,String haveAuth){
        
        List<String> haveMenu = new ArrayList<String>();
        
        allMenu.forEach((sysMenu) ->{
            if (RightsHelper.testRights(haveAuth, sysMenu.getMenuId())) {
                if(!StringUtil.isEmpty(sysMenu.getMenuSign()) ){
                    haveMenu.add(sysMenu.getMenuSign()+ ":" +operator);
                }
            }
        });
        return haveMenu;
    }
    //清除缓存
    public void clearCached() {
      PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
      super.clearCache(principals);
    }
    
}
